<?php

namespace NorthernLights\JetBrainsLicensing;

use Klein\Request;
use NorthernLights\JetBrainsLicensing\Cryptography\Rsa;
use NorthernLights\JetBrainsLicensing\Exception\XmlGenerationException;

/**
 * Class Server
 * @package NorthernLights\JetBrainsLicensing
 */
class Server
{
    /** @var ServerAction */
    private $action;

    /** @var Request */
    private $request;

    /** @var string */
    private $xmlString;

    /**
     * Server constructor.
     *
     * @param Request $requestAction
     * @param PrivateKeyFile $pemFile
     *
     * @throws XmlGenerationException
     */
    public function __construct(Request $requestAction, PrivateKeyFile $pemFile)
    {
        $this->action  = new ServerAction($requestAction);
        $this->request = $requestAction;
        $rsa           = new Rsa($pemFile);
        $xmlString     = $this->prepareXml();

        // Prepend signature
        $this->xmlString = sprintf('<!-- %s -->', $rsa->sign($xmlString)) . PHP_EOL . $xmlString;
    }

    /**
     * Same as getResponse
     *
     * @return string
     */
    public function __toString(): string
    {
        return $this->xmlString;
    }

    /**
     * @return string
     */
    public function getResponse(): string
    {
        return $this->xmlString;
    }

    /**
     * Prepare XML string
     *
     * @return string
     * @throws XmlGenerationException
     */
    protected function prepareXml(): string
    {
        $domXml = $this->action->getResponseXml();
        $this->action->getXmlFactory()->setDomDocumentOption('formatOutput', true);

        $xmlString = trim($domXml->saveXML($domXml, LIBXML_NOEMPTYTAG));

        if (empty($xmlString)) {
            throw new XmlGenerationException('XML is not valid');
        }

        // Fixme: This is not good approach, but workaround since SimpleXMLElement won't accept LIBXML_NOXMLDECL
        $xmlString = trim(preg_replace('/^<\?xml(.)+\?>/i', '', $xmlString));

        return $xmlString;
    }
}
